
import json
from qiniu import Auth, put_data
from homes.models import Area, House
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.http import JsonResponse
import datetime
import json

from django.core.paginator import Paginator
from qiniu import Auth, put_data

from homes.models import Area, House, HouseImage
from django.http import JsonResponse
from django.shortcuts import render

from django.views import View
from django.core.cache import cache
from django.conf import settings
from homes.models import Area, House

# 城区列表
from django.conf import settings
from users.models import User

from homes.models import Facility
from orders.models import Order
# Create your views here.
# /api/v1.0/areas
class AreaView(View):
    def get(self, request):
        try:
            areas= Area.objects.filter().values('id', 'name')
            area_list = []

            for areases in areas:
                areas_data = {
                    'aid':areases['id'],
                    'aname': areases['name']
                }
                area_list.append(areas_data)
        except Exception as e:
            return JsonResponse({
                'errno': 400,
                'errmsg': '获取地址信息出错'
            })

        return JsonResponse({
            'errno': 0,
            "errmsg": '获取成功',
            "data": area_list

        })


# 发布方源
# # /api/v1.0/houses
# class HouseView(View):
#     def post(self, request):
#         req_data = json.loads(request.body)
#
#         title = req_data.get('title')
#         price = req_data.get('price')
#         area_id = req_data.get('area_id')
#         address = req_data.get('address')
#         room_count = req_data.get('room_count')
#         acreage = req_data.get('acreage')
#         unit = req_data.get('unit')
#         capacity = req_data.get('capacity')
#         beds = req_data.get('beds')
#         deposit = req_data.get('deposit')
#         min_days = req_data.get('min_days')
#         max_days = req_data.get('max_days')
#         facility = req_data.get('facility') # list，[设施id, 设施id, ...]
#
#         user = request.user
#         if not all([title, price, area_id, address, room_count, acreage, unit, capacity,
#                     beds, deposit, min_days, max_days, facility]):
#             return JsonResponse({
#                 "errno": 400,
#                 "errmsg": "缺少必传参数"
#             })
#         try:
#             house= House.objects.create(
#                 title=title, price=price,
#                 area_id=area_id, address=address,
#                 room_count=room_count, acreage=acreage,
#                 unit=unit, capacity=capacity,
#                 beds=beds, deposit=deposit,
#                 min_days=min_days, max_days=max_days,
#                 user_id=request.user.id
#             )
#             # 保存房屋设置
#             for facility_id in facility:
#                 house.facility.add(facility_id)
#         except Exception as e:
#             print(e)
#             return JsonResponse({
#                 "errno": 4101,
#                 "errmsg": '保存房屋信息失败'
#             })
#
#         return JsonResponse({
#             "errno": 0,
#             "errmsg": '发布成功',
#             "data": {
#                 'house_id': house.id
#             }
#         })



# /api/v1.0/houses/[int:house_id]/images
# class House_Image(View):
#     def post(self, request):
#         req_data = json.loads(request.body)
#         house_image = req_data.get('house_image')
#         if not house_image:
# class House_Image(View):
#     def post(self, request):
#         req_data = json.loads(request.body)
#         house_image = req_data.get('house_image')
#         if not house_image:
#             return JsonResponse({
#                 'errno': 400,
#                 'errmsg': '文件参数不存在'
#             })
#         else:
#             access_key = settings.QINIU_ACCESS_KEY
#
#             secret_key = settings.QINIU_SECRET_KEY
#             # 构建鉴权对象
#             q = Auth(access_key, secret_key)
#             # 要上传的空间－七牛云的空间
#             bucket_name = 'ihome-41'
#             # 上传后保存的文件名
#             key = None
#             # 生成上传 Token，可以指定过期时间等
#             token = q.upload_token(bucket_name, key, )
#             # 要上传文件的本地路径
#             ret, info = put_data(up_token=token, key=key, data=house_image.read())
#             print(info)
#
#             image_file = settings.URL + ret['hash']
#             print(image_file)
#
#             print(ret['hash'])
#             user = User.objects.get(pk=req_data.id)
#             user.avatar = ret['hash']
#             user.save()
#
#             # 3业务数据处理
#
#             # 4构建响应
#             data = {"avatar_url": image_file}
#         return JsonResponse({
#             'errno': 0,
#             'errmsg': '头像上传成功',
#             'data': data
#         })



# S上传房源图片
class HomeImage(View):
    def post(self, request, house_id):
        house_image = request.FILES.get('house_image')
        if house_image is None:
            return JsonResponse({
                'errno': '4103',
                'errmsg': '图片错误'
            })
        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            # logger.info(e)
            return JsonResponse({
                'errno': '4103',
                'errmsg': '房屋不存在'
            })

        access_key = settings.QINIU_ACCESS_KEY
        secret_key = settings.QINIU_SECRET_KEY
        # 构建鉴权对象
        q = Auth(access_key, secret_key)
        # 要上传的空间－七牛云的空间
        bucket_name = 'ihome-41'
        # 上传后保存的文件名
        key = None
        # 生成上传 Token，可以指定过期时间等
        token = q.upload_token(bucket_name, key, )
        # 要上传文件的本地路径
        ret, info = put_data(up_token=token, key=key, data=house_image.read())
        print(info)

        image_file = ret['hash']
        print(image_file)
        houseimage = HouseImage.objects.create(house=house, url=image_file)

        house.index_image_url = image_file
        house.save()
        # 4构建响应
        data = {"url": settings.QINIU_URL + houseimage.url}
        return JsonResponse({
            "data": data,
            "errno": "0",
            "errmsg": "图片上传成功"
        })




# 我的房屋列表
# /api/v1.0/user/houses
class HouseListView(View):
    """房屋列表"""

    def get(self, request):
        # 获取当前登录用户
        user = request.user

        # 查询数据库
        # houses_model_list = House.objects.filter(user_id=user.id)
        houses_model_list = user.houses.all()

        # 构造返回结果
        houses = []
        for house in houses_model_list:
            houses.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time,
                "house_id": house.id,
                "img_url": 'http://qszogrsfy.hd-bkt.clouddn.com/'+house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": 'http://qszogrsfy.hd-bkt.clouddn.com/'+house.user.avatar.name
            })
        # 返回响应结果
        return JsonResponse({
            'data': {'houses': houses},
            "errmsg": "ok",
            "errno": "0"
        })
#/api/v1.0/houses/index

class HouseIndexView(View):
    """
    首页推荐房间显示
    """
    def get(self, request):
        # 无请求参数
        data = []
        try:
            House_lists = House.objects.all()
            for home_list in House_lists:

                data.append({  # 加入到data
                    "house_id": home_list.id,  # 房屋id
                    "img_url": "http://qszogrsfy.hd-bkt.clouddn.com/" + home_list.index_image_url,  # 房屋主图片
                    "title": home_list.title,  # 房屋标题
                })
            data = data[1:6]
        except Exception as e:  # 发生未知错误
            return JsonResponse({"data": {}, "errmsg": "UNKOWNERR - 未知错误", "errno": "4501"})
        return JsonResponse({"data": data, "errmsg": "ok", "errno": "0"})


class HouseDetailView(View):
    """房屋详情"""

    def get(self, request, house_id):
        # 查询数据库
        try:
            house = House.objects.get(id=house_id)
        except House.DoesNotExist:
            return JsonResponse({'errno': 400, 'errmsg': '参数house_id有误'})

        house_dict = {
            "hid": house.id,
            "user_id": house.user.id,
            "user_name": house.user.username,
            "user_avatar": settings.QINIU_URL + house.user.avatar.name if house.user.avatar.name else "",
            "title": house.title,
            "price": house.price,
            "address": house.address,
            "room_count": house.room_count,
            "acreage": house.acreage,
            "unit": house.unit,
            "capacity": house.capacity,
            "beds": house.beds,
            "deposit": house.deposit,
            "min_days": house.min_days,
            "max_days": house.max_days,
        }

        # 房屋图片
        img_urls = []
        for image in house.houseimage_set.all():
            img_urls.append(settings.QINIU_URL + image.url)
        house_dict["img_urls"] = img_urls

        # 房屋设施
        facilities = []
        for facility in house.facility.all():
            facilities.append(facility.id)
        house_dict["facilities"] = facilities

        # 评论信息
        comments = []
        orders = Order.objects.filter(house=house, status=Order.ORDER_STATUS["COMPLETE"],
                                      comment__isnull=False).order_by("-update_time")[0:30]
        for order in orders:
            comment = {
                "comment": order.comment,  # 评论的内容
                "user_name": order.user.username if order.user.username != order.user.mobile else "匿名用户",  # 发表评论的用户
                "ctime": order.update_time.strftime("%Y-%m-%d %H:%M:%S")  # 评价的时间
            }
            comments.append(comment)
        house_dict["comments"] = comments

        # 返回响应结果
        return JsonResponse({
            'data': {
                'house': house_dict,
                'user_id': request.user.id if request.user.is_authenticated else -1
            },
            "errmsg": "OK",
            "errno": 0
        })


class HousesView(View):
    """发布房源/房屋数据搜索"""
    def post(self, request):
        """发布房源"""
        user = request.user

        # 接收参数
        data_dict = json.loads(request.body)
        title = data_dict.get('title')
        price = data_dict.get('price')
        area_id = data_dict.get('area_id')
        address = data_dict.get('address')
        room_count = data_dict.get('room_count')
        acreage = data_dict.get('acreage')
        unit = data_dict.get('unit')
        capacity = data_dict.get('capacity')
        beds = data_dict.get('beds')
        deposit = data_dict.get('deposit')
        min_days = data_dict.get('min_days')
        max_days = data_dict.get('max_days')
        facility = data_dict.get('facility')

        # 验证数据完整
        if not all([title, price, area_id, address, room_count,
                    acreage, unit, capacity, beds, deposit, min_days, max_days, facility]):
            return JsonResponse({'errno': 400, 'errmsg': '缺少必传参数'})
        try:
            price = int(float(price) * 100)
            deposit = int(float(deposit) * 100)
        except Exception:
            return JsonResponse({"errno": 400, "errmsg": "参数错误"})

        try:
            area = Area.objects.get(id=area_id)
        except Exception:
            return JsonResponse({"errno": 400, "errmsg": "地址不存在"})

        # # 处理设施列表
        # facilities =[]
        # if facility:
        #     for fac_id in facility:
        #         facilities.append(Facility.objects.get(id=fac_id))

        # 将数据写入数据库
        try:
            house = House.objects.create(
                title=title,
                price=price,
                area_id=area_id,
                address=address,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days,
                user_id=user.id,
            )

            for item in facility:
                facility = Facility.objects.get(id=item)
                house.facility.add(facility)

        except Exception:
            return JsonResponse({"errno": 400, "errmsg": "发布失败"})

        return JsonResponse({
            "errno": "0",
            "errmsg": "发布成功",
            "data": {"house_id": house.id}
        })

    def get(self, request):
        """搜索房屋"""
        # 接收参数
        area_id = request.GET.get('aid')
        start_date_str = request.GET.get('sd', None)
        end_date_str = request.GET.get('ed', None)
        sort_key = request.GET.get('sk')
        page = request.GET.get('p', 1)  # 页数非必传, 不传默认是1

        # 校验参数
        # 校验区域id是否存在
        if area_id:
            try:
                Area.objects.get(id=area_id)
            except Area.DoesNotExist:
                return JsonResponse({'errno': 400, 'errmsg': '参数aid有误'})
        # 对日期进行相关处理
        try:
            start_date = None
            end_date = None
            if start_date_str:
                start_date = datetime.datetime.strptime(start_date_str, '%Y-%m-%d')
            if end_date_str:
                end_date = datetime.datetime.strptime(end_date_str, '%Y-%m-%d')
            # 如果开始时间大于或者等于结束时间,就报错
            if start_date and end_date:
                if start_date > end_date:
                    return JsonResponse({'errno': 400, 'errmsg': '时间参数有误'})
        except Exception:
            return JsonResponse({"errno": 400, "errmsg": "参数错误"})
        # 处理页数
        if page:
            try:
                page = int(page)
            except Exception:
                return JsonResponse({'errno': 400, 'errmsg': '参数page有误'})

        # 房屋搜索: 根据过滤参数, 筛选出没有冲突的订单
        # 构造过滤参数列表
        filter_dict = {}

        # 城区
        if area_id:
            # 如果选择了城区, 就将城区id添加到过滤参数列表中
            filter_dict['area_id'] = area_id

        # 定义订单列表
        conflict_orders = []
        # 根据时间查询所有没有冲突的订单
        if start_date and end_date:
            # 如果订单的开始时间 < 结束时间 and 订单的结束时间 > 开始时间
            conflict_orders = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
        elif start_date:
            # 订单的结束时间 > 开始时间
            conflict_orders = Order.objects.filter(end_date__gt=start_date)
        elif end_date:
            # 订单的开始时间 < 结束时间
            conflict_orders = Order.objects.filter(begin_date__lt=end_date)

        if conflict_orders:
            # 获取所有的房子id
            house_ids = [order.house_id for order in conflict_orders]
            if house_ids:
                filter_dict['id__in'] = house_ids

        # 根据filter_list里边的过滤参数,搜索房子数据
        houses = House.objects.filter(**filter_dict)
        # 根据sort_key对查询结果进行排序
        if sort_key == 'booking':
            houses_data = houses.order_by('-order_count')
        elif sort_key == 'price-inc':
            houses_data = houses.order_by('price')
        elif sort_key == 'price-des':
            houses_data = houses.order_by('-price')
        else:
            houses_data = houses.order_by('-create_time')

        # 分页处理, 每页显示3条数据
        paginator = Paginator(houses_data, 3)
        page_houses = paginator.page(page)
        # 获取总页数
        total_page = paginator.num_pages

        # 构造响应结果
        houses = []
        for house in page_houses:
            houses.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time,
                "house_id": house.id,
                "img_url": settings.QINIU_URL + house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": settings.QINIU_URL + house.user.avatar.name
            })
        data = {
            'houses': houses,
            'total_page': total_page
        }

        # 返回响应结果
        return JsonResponse({
            "data": data,
            "errmsg": "请求成功",
            "errno": "0"
        })


